package gin

import (
	"gitee.com/zawei/yggdrasil/api/yggdrasil/api"
	"gitee.com/zawei/yggdrasil/pkg/errors"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
	"google.golang.org/genproto/googleapis/rpc/code"
	"google.golang.org/protobuf/encoding/protojson"
)

func response(c *gin.Context, resp *api.HttpResponse) {
	data, _ := protojson.Marshal(resp)
	switch c.NegotiateFormat(binding.MIMEJSON, binding.MIMEPROTOBUF) {
	case binding.MIMEJSON:
		c.Data(int(resp.Status.Code), binding.MIMEJSON, data)
	case binding.MIMEPROTOBUF:
		c.ProtoBuf(int(resp.Status.Code), resp)
	default:
		c.JSON(int(resp.Status.Code), resp)
	}
}

func Success(c *gin.Context, data proto.Message) {
	rsp, err := ptypes.MarshalAny(data)
	if err != nil {
		response(c, &api.HttpResponse{
			Status: &api.HttpResponse_Status{
				Code:    errors.CodeToHttpStatus(code.Code_INTERNAL),
				Message: err.Error(),
				Status:  code.Code_OK,
			},
		})
		return
	}
	response(c, &api.HttpResponse{
		Status: &api.HttpResponse_Status{
			Code:    errors.CodeToHttpStatus(code.Code_OK),
			Message: code.Code_OK.String(),
			Status:  code.Code_OK,
		},
		Data: rsp,
	})

}

func Error(c *gin.Context, err error) {
	_ = c.Error(err)
	st := errors.FromError(err)
	reason := errors.Reason(err)
	if reason != "" {
		c.Writer.Header().Set("x-yggdrasil-reason", reason)
	}
	response(c, &api.HttpResponse{
		Status: &api.HttpResponse_Status{
			Code:    st.HttpCode(),
			Message: st.Message(),
			Status:  st.Code(),
			Details: st.Proto().Details,
		},
	})
}
